<?php
/**
 * memcache
 */
namespace yphp;

class Memcache extends Instance
{
    # 私有的分布式对象
    private $distribute;

    # 节点列表
    private static $nodes = [];

    /**
     * 构造函数，获取配置的memcache数组，并初始化节点
     * @return 单例只能执行一次
     */
    function construct()
    {
        if (empty(self::$nodes)){
            foreach (Config::nosql('memcache') as $k => $v) {
                is_int($k) ? self::$nodes[$v] = 1 : self::$nodes[$k] = $v;
            }
        }
        $this->distribute = Distribute::instance(self::$nodes);
        return self::single();
    }

    // 获取节点列表
    static function node()
    {
        return self::$nodes;
    }

    # 连接列表
    private static $linkArr = [];

    // 获取节点
    function link($key)
    {
        return self::connect(self::instance()->distribute->getNode($key));
    }

    // 连接并存储节点信息
    private static function connect($node)
    {
        if (key_exists($node, self::$linkArr)) {
            $link = self::$linkArr[$node];
        } else {
            $link = new \Memcache();
            call_user_func_array([$link, 'connect'], explode(':', $node));
            self::$linkArr[$node] = $link;
        }
        return $link;
    }

    /**
     * @param $name 方法名
     * @param $arguments  参数数组
     * @return 返回结果
     * 魔术方法，根据参数调用对应的方法，如果存在get2方法，则额外处理
     */
    static function __callStatic($name, $arguments)
    {
        $alias = substr($name, -1) === '2';
        $name = $alias ? substr($name, 0, -1) : $name;
        $key = $alias ? array_shift($arguments) : $arguments[0];
        $link = self::instance()->link($key);
        return call_user_func_array([$link, $name], $arguments);
    }

    // 关闭所有链接
    static function closeAll()
    {
        foreach (self::$linkArr as $link) {
            $link->close();
        }
    }

    // 获取节点信息
    static function getStats($node)
    {
        return self::connect($node)->getStats();
    }

    // 清空某个节点的数据
    static function flush($node)
    {
        return self::connect($node)->flush();
    }

    // 清空所有节点数据并返回清空的节点和状态
    static function flushAll()
    {
        $res = [];
        foreach (self::$linkArr as $node => $link) {
            $res[$node] = $link->flush();
        }
        return $res;
    }
}